package main

import (
	"bytes"
	"fmt"
	"io"
	"net"
	"time"

	"gitee.com/zhaoqinghuan/rpc/transport"
)

func main1() {
	tcpAddr, err := net.ResolveTCPAddr("tcp4", "127.0.0.1:5678") // 解析 TCP 地址字符串 "127.0.0.1:5678" 为 *net.TCPAddr 类型的地址，使用 IPv4 协议。
	transport.CheckError(err)
	listener, err := net.ListenTCP("tcp4", tcpAddr) // net.ListenTCP 函数使用 tcpAddr 创建一个 TCP 监听器，等待传入的 TCP 连接
	transport.CheckError(err)
	fmt.Println("Waiting for client connection ...")
	conn, err := listener.Accept() // listener.Accept 阻塞并等待一个新的客户端连接，返回一个 net.Conn 对象（表示新连接）和一个错误对象
	transport.CheckError(err)

	// 连接建立后系统会自动向客户端分配一个 49152 ~ 65535 之间的端口

	fmt.Printf("establish connection to client %s \n", conn.RemoteAddr().String()) // 打印一条消息，告知已建立到客户端的连接，并显示客户端的地址
	time.Sleep(5 * time.Second)                                                    // 阻阻塞当前协程 等待客户端发送消息
	request := make([]byte, 256)                                                   // 创建一个长度为 255 字节的字节切片，用来保存客户端发送的数据。
	buffer := bytes.Buffer{}                                                       // 创建一个字节缓冲区，用于临时存储和处理接收到的数据。
	for {
		n, err := conn.Read(request) // 从连接中读取数据到 request 切片
		if err == io.EOF {           // 如果监控到客户端断开连接，打印缓冲区内容并跳出循环。
			fmt.Println(buffer.String())
			break
		}
		fmt.Printf("receive request %s \n", string(request[:n])) // 打印接收到的数据（request 切片中的前 n 个字节 ）这里没有魔数是因为魔数字节数无法转换为UTF8字符
		data := request[:n]                                      // 将 request 切片中前 n 个字节的数据赋值给 data 切片
		for {
			pos := bytes.Index(data, transport.MAGIC) //在 data 中查找 transport.MAGIC 分隔符的位置。
			if pos >= 0 {                             // 检查是否找到了分隔符。
				if pos == 0 { // 如果分隔符在开头，并且缓冲区有内容，打印缓冲区内容并重置缓冲区
					if buffer.Len() > 0 {
						fmt.Println(buffer.String())
						buffer.Reset()
					}
				} else if pos > 0 { // 如果分隔符在数据中间或末尾，将分隔符之前的数据写入缓冲区，打印缓冲区内容并重置缓冲区。
					buffer.Write(data[:pos])
					fmt.Println(buffer.String())
					buffer.Reset()
				}
				data = data[pos+len(transport.MAGIC):]
			} else { // 如果没有找到分隔符，将 data 中的数据写入缓冲区并跳出嵌套循环。
				buffer.Write(data)
				break
			}
		}
	}
	conn.Close()
}
